package com.netscenery.yang.model;

import java.io.IOException;
import java.util.ArrayList;

import org.jdom2.Document;
import org.jdom2.Element;
import org.jdom2.JDOMException;
import org.jdom2.Namespace;
import org.jdom2.input.SAXBuilder;
import org.jdom2.output.Format;
import org.jdom2.output.XMLOutputter;

import com.netscenery.util.ErrTag;
import com.netscenery.util.FileUtil;
import com.netscenery.util.XMLTag;
import com.netscenery.yang.YangStatement;
import com.netscenery.yang.designer.LeafFieldMap;
import com.netscenery.yang.designer.ListFieldMap;
import com.netscenery.yang.designer.MapInfo;
import com.netscenery.yang.designer.MethodInfo;
import com.netscenery.yang.designer.Parameter;
import com.netscenery.yang.parser.YangParser;
import com.netscenery.yang.parser.YangParserEnv;
import com.netscenery.yang.parser.YangParserException;
import com.netscenery.yang.writer.YangFormatter;

public class MainModule extends Module {
	private String namespace;
	private String prefix;
	/**
	 * 
	 * @param env
	 * @param name
	 * @throws ModelException 
	 */
	public MainModule(Env env,String name) throws ModelException{
		super(env,name);
		if (null != this.getEnv()){
			if(null != this.getEnv().getModule(name)){
				return;
			}
			
			this.getEnv().setCurModule(this);
		}
		
	}
	/**
	 * 
	 * @param env
	 * @param name
	 * @param prefix
	 * @param namespace
	 * @throws ModelException 
	 */
	public MainModule(Env env,String name,String prefix, String namespace) throws ModelException{
		this(env,name);
		this.prefix = prefix;
		this.namespace = namespace;
	}
	/**
	 * 	��ȡ����ռ�
	 * @return
	 */
	public String getNamespace() {
		return namespace;
	}
	/**
	 * ��������ռ�
	 * @param namespace
	 */
	public void setNamespace(String namespace) {
		this.namespace = namespace;
	}
	/**
	 * ��ȡǰ׺
	 * @return
	 */
	public String getPrefix() {
		return prefix;
	}
	/**
	 * ����ǰ׺
	 * @param prefix
	 */
	public void setPrefix(String prefix) {
		this.prefix = prefix;
		if (null != this.env){
			env.addPrefix(prefix);
		}
	}






	
	@Override
	public Validator validate() {
		Validator validator = new Validator();
		
		if (isNullString(name)){
			validator.setIsValid(false);
			validator.addMsg(new Message(this,ErrTag.ERROR,ErrorCode.COMMON_INVALIDNAME));
		}
		if (isNullString(prefix)){
			validator.setIsValid(false);
			validator.addMsg(new Message(this,ErrTag.ERROR,"prefix is mandatory."));
		}
		
		if (isNullString(namespace)){
			validator.setIsValid(false);
			validator.addMsg(new Message(this,ErrTag.ERROR,"namespace is mandatory."));
		}
		
		if (!checkName(this.name)){
			validator.setIsValid(false);
			validator.addMsg(new Message(this,ErrTag.ERROR,ErrorCode.COMMON_INVALIDNAME));
		}
		
		Validator sValidator = super.validate();
		validator.copy(sValidator);
		return validator;
	}

	@Override
	public boolean isFieldMandatory(String field) {
		// TODO Auto-generated method stub
		return false;
	}
	
	public static void main(String[] args) throws JDOMException, IOException {
/*		MainModule mainModule = new MainModule("zxr10-mpls","mpls",
				"http://www.netscenery.com.cn/zxr10/netconf/schema/rosng/mpls");

		mainModule.setOrganization("netscenery Corporation");
		mainModule.setContact("         netscenery Corporation\n" +
				"         Nanjing Institute of netscenery Corporation\n" +
				"         No.68 Zijinghua Rd. Yuhuatai District, Nanjing, China\n" +
				"         Tel: +86-25-52870000");
		mainModule.setDescription("ZXR10 ROSNG:the netconf model for mpls");
		
		Include include = new Include("netconf");
		include.setRevisionDate("2013-01-13");
		mainModule.addInclude(include);
		Import importElement = new Import("netconf","netc");
		importElement.setRevisionDate("2013-01-13");
		mainModule.addImport(importElement);
		
		Import importElement2 = new Import("zxr10-netconf-defs","ncd");
		importElement2.setRevisionDate("2013-01-15");
		mainModule.addImport(importElement2);*/
		MainModule imp = null;
		String yangStr = FileUtil.readFile2String("d:/zxr10-netconf-defs@2013-06-08.yang");
		YangParser parser = new YangParser(yangStr);

		YangParserEnv env = parser.getEnv();
		env.setBeginColumn(1);
		env.setBeginLine(1);
		env.setBeginPos(0);
		env.setEndPos(yangStr.length());
		
		YangStatement statement = null;
		try {
			parser.parseYang();
		} catch (YangParserException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			System.out.println(e.toString());
			return;
		}
		statement = parser.getStatement();
		if (null == statement){
			return;
		}
		try {
			try {
				imp= (MainModule) ModelElement.parseYANG(new Env(), statement);
			} catch (ModelException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		} catch (YangParserException e1) {
			// TODO Auto-generated catch block
			
			if (e1.getErrorTag().equals(ErrTag.ERROR)){
				e1.printStackTrace();
				return;
			}
			
			System.out.println(e1.toString());
		}
		YangFormatter formatter = null;
		String yangStrnew = null;
		formatter = new YangFormatter();
		formatter.setPrettyFormatter();

		yangStrnew = imp.toYANGString(formatter);
		System.out.println(yangStrnew);
		
		MainModule mainModule = null;
		
		SAXBuilder builder = new SAXBuilder();
		Document myDocument = builder.build("d:/zxr10-aps@2013-07-18.xml");
		Element root = myDocument.getRootElement();
		Env mainEnv = new Env();
		mainEnv.addMainModule(imp);
		try {
			mainModule =(MainModule) ModelElement.parseXML(mainEnv, root);
		} catch (ModelException e) {
			if (e.getErrorTag().equals(ErrTag.ERROR)){
			e.printStackTrace();
			return;
		}
		
		System.out.println(e.toString());
		}
		

		
//		yangStr = YangParser.readFile2String("d:/zxr10-netconf@2013-05-27.yang");
//		parser = new YangParser(yangStr);
//
//		env = parser.getEnv();
//		env.setBeginColumn(1);
//		env.setBeginLine(1);
//		env.setBeginPos(0);
//		env.setEndPos(yangStr.length());
//		
//		statement = null;
//		try {
//			parser.parseYang();
//		} catch (YangParserException e) {
//			// TODO Auto-generated catch block
//			e.printStackTrace();
//			System.out.println(e.toString());
//			return;
//		}
//		statement = parser.getStatement();
//		if (null == statement){
//			return;
//		}
//		Env mainEnv = new Env();
//		mainEnv.addMainModule(imp);
//		try {
//			mainModule= (MainModule) ModelElement.parseYANG(mainEnv, statement);
//		} catch (YangParserException e) {
//			if (e.getErrorTag().equals(ErrTag.ERROR)){
//				e.printStackTrace();
//				return;
//			}
//			
//			System.out.println(e.toString());
//		}
//		
		
		formatter = new YangFormatter();
		formatter.setPrettyFormatter();

		yangStrnew = mainModule.toYANGString(formatter);
		System.out.println(yangStrnew);
		
		System.out.println(mainModule.toXMLString());
		//System.out.println(mainModule.schemaToString());
	}

	/**
	 * ����һ����ģ��
	 * @param env
	 * @param name
	 * @return
	 * @throws ModelException 
	 */
	public static ModelElement create(Env env,  String name) throws ModelException {	
	
		if (null == name){
			return null;
		}
		
		
		MainModule m = new MainModule(env,name);		
		return m;
	}
	@Override
	public void update() {
		// TODO Auto-generated method stub
		
	}

//	public Element generateSchema(){
//		Element root = new Element("root");
//		Namespace ns = Namespace.getNamespace(this.getPrefix(), this.getNamespace());
//		//root.addNamespaceDeclaration(ns);
//		//root.setNamespace(ns);
//		int size = this.getNodesNumber();
//		for (int i = 0; i < size; i++){
//			Node node = this.getNode(i);
//			if (null == node){
//				continue;
//			}
//			
//			Element rn = node.generateSchema(ns);
//			if(null != rn){
//				root.addContent(rn);
//			}
//		}
//		
//		return root;
//	}
//	
//	public String schemaToString(){
//		String XMLString = null;
//		Element e = generateSchema();
//		XMLOutputter xmloutput = new XMLOutputter();
//		Document doc = new Document();
//		doc.setRootElement(e);
//		
//		xmloutput.setFormat(Format.getPrettyFormat());
//		XMLString = xmloutput.outputString(doc);
//		return XMLString;
//	}

	

}
